#include "pusher/http_stream_server.hpp"
#include "utils/log.hpp"

#include <iostream>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <sys/socket.h>
#include <unistd.h>

// Start 函数，创建一个循环等待 socket 连接并调用 http 推流
void HttpStreamServer::Start()
{
    if (_running) {
        std::cerr << "http流已经开启" << std::endl;
        return;
    }
    _running = true;
    _acceptThread = std::thread(&HttpStreamServer::AcceptLoop, this);
}


void HttpStreamServer::Stop()
{
    if (!_running) {
        std::cerr << "http流已经关闭" << std::endl;
        return;
    }
    _running = false;

    if (_server_fd != -1) close(_server_fd);
    LOG_DEBUG("关闭 server_fd 正常");
    if (_acceptThread.joinable()) _acceptThread.join();
    LOG_DEBUG("关闭http流正常");
}



// 创建本地 socket 绑定 ip 和端口，等待远程连接
void HttpStreamServer::AcceptLoop()
{
    LOG_DEBUG("调用 AcceptLoop");
    _server_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (_server_fd < 0) {
        perror("socket 创建失败");
        return;
    }

    int opt = 1;
    struct timeval timeout = {2, 0};
    // 端口可重用
    setsockopt(_server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
    // accept 接收超时机制，防止阻塞在accept这里，导致线程无法join
    setsockopt(_server_fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));

    sockaddr_in addr{};
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = INADDR_ANY;
    addr.sin_port = htons(_port);

    if (bind(_server_fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
        perror("连接失败");
        return;
    }

    if (listen(_server_fd, 4) < 0) {
        perror("监听失败");
        return;
    }

    LOG_DEBUG("[HTTP] 监听端口 ");

    while (_running) {
        sockaddr_in client_addr;
        socklen_t len = sizeof(client_addr);

        LOG_DEBUG("[HTTP] 等待连接中...");
        int client_fd = accept(_server_fd, (struct sockaddr*)&client_addr, &len);

        // debug， 打印客户端连接请求头
        char request[1024] = {0};
        int received = recv(client_fd, request, sizeof(request) - 1, 0);
        if (received <= 0) {
            std::cerr << "[HTTP] 接受请求失败， 关闭 fd = " << client_fd << std::endl;
            close(client_fd);
            return;
        }

        std::string req_str(request);
        LOG_DEBUG("[HTTP] 请求内容:\n");
        
        if (!_running) break;
        
        if (client_fd < 0) {
            if (errno == EAGAIN || errno == EWOULDBLOCK) {
                continue;
            }
            perror("[HTTP] accept 失败");
            continue;
        }

        LOG_DEBUG("[HTTP] 客户端已连接 IP: ", inet_ntoa(client_addr.sin_addr));
        if (client_fd < 0) continue;

        std::thread(&HttpStreamServer::HandleClient, this, client_fd).detach();
    }
}